#pragma once

#ifndef LHJ_CORE_DATAS_SCREEN_RAW_DATA_H__
#define LHJ_CORE_DATAS_SCREEN_RAW_DATA_H__

#include <stdint.h>
#include <vector>
#include <map>
#include <string>
#include "model.h"

namespace cores
{
    namespace datas
    {

        using namespace std;
        using namespace models::terminal;

        class SRData
        {
        public:
            SRData();
            virtual ~SRData();
            virtual bool toChar(const uint8_t *buffer, const int &len, char &value) = 0;

        protected:
            virtual bool bitIsOn(const uint8_t * buffer, const int &len, int index);
        };

        /**
         * @attention 存储LED数据的笔画序列
         */
        class SRNumData : public SRData
        {
        public:
            SRNumData(const vector<int> &indexs);
            virtual ~SRNumData();

        protected:
            bool toChar(const uint8_t *buffer, const int &len, char &value);

        private:
            vector<int> _indexs;

            /**
             * @brief 数字显示
             */
            static map<string, char> _numMap;
        };

        /**
         * @brief 存储LED小数点的序号
         */
        class SRPtData : public SRData
        {
        public:
            SRPtData(const int &index);
            virtual ~SRPtData();

        protected:
            bool toChar(const uint8_t *buffer, const int &len, char &value);

        private:
            int _index;
        };

        class SR2ValHelper
        {
        public:
            /**
             * @brief 析构函数
             */
            virtual ~SR2ValHelper();

            /**
             * @brief 二进制数据流转换成显示屏数据
             */
            ScreenValData HexChar2ScreenVal(const uint8_t *buffer, const int &len);

        protected:
            /**
             *  加油金额数字序号
             */
            vector<SRData *> _amounts;

            /**
             *  油量升数
             */
            vector<SRData *> _volumes;

            /**
             *  单价
             */
            vector<SRData *> _prices;

            /**
             * @brief 构造函数
             */
            SR2ValHelper(const uint32_t &screenNumber_);

            /**
             * @brief 构造函数
             */
            SR2ValHelper(const string &screenModel_);

            /**
             * @brief 将数据流转换成数字字符串
             */
            virtual string toString(const uint8_t *buffer,
                                    const int &len,
                                    const vector<SRData *> &datas,
                                    bool &err);

        private:
            /**
             * @brief 显示屏编号
             */
            uint32_t _screenNumber{0};

            /**
             * @brief 显示屏型号
             */
            string _screenModel;
        };

        /**
         * @brief   本类用于管理SR2ValHelper的子类对象，每个对象处理一个显示屏的数据解析，SR2ValHelper的子类可以使用显示屏类型编号或显示屏型号
         *          对显示屏数据调用使用方法：
         *          auto screenValData = SR2ValueManager::getInstance()->getSR2ValHelper(1)->HexChar2ScreenVal(buffer, len);   // 1表示显示屏处理的分类代码
         *          或
         *          auto screenValData = SR2ValueManager::getInstance()->getSR2ValHelper("显示屏型号")->HexChar2ScreenVal(buffer, len);    
         *          
         */
        class SR2ValueManager
        {
        protected:
            SR2ValueManager();

        private:
            map<uint32_t, SR2ValHelper *> _instancesByScreenNumber;
            map<string, SR2ValHelper *> _instancesByScreenModel;

        public:
            virtual ~SR2ValueManager();

            void registerSR2ValueHelper(const uint32_t &screenNumber_, SR2ValHelper *helper_);
            void registerSR2ValueHelper(const string &screenModel_, SR2ValHelper *helper);

            void unregisterSR2ValueHelper(const uint32_t &screenNumber_, SR2ValHelper *helper_);
            void unregisterSR2ValueHelper(const string &screenModel_, SR2ValHelper *helper);

            SR2ValHelper *getSR2ValHelper(const uint32_t &screenNumber_);
            SR2ValHelper *getSR2ValHelper(const string &screenModel_);

            static SR2ValueManager *getInstance();
        };
    }
}

#endif